package edu.sdjzu.exam.service.exam.impl;



import cn.dev33.satoken.stp.StpUtil;
import edu.sdjzu.exam.dto.*;
import edu.sdjzu.exam.mapper.exam.ExamMapper;
import edu.sdjzu.exam.mapper.exam.ExamQuestionsMapper;
import edu.sdjzu.exam.domain.exam.Exam;
import edu.sdjzu.exam.domain.exam.ExamQuestion;

import edu.sdjzu.exam.service.question.QuestionService;
import edu.sdjzu.exam.service.exam.ExamService;
import edu.sdjzu.exam.service.course.CourseManagementService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ExamServiceImpl implements ExamService {

    private final ExamMapper examMapper;
    private final ExamQuestionsMapper examQuestionsMapper;
    private final QuestionService questionService;
    private final CourseManagementService courseManagementService;

    @Override
    @Transactional
    public Long createExam(ExamCreateDTO createDTO) {
        Long createdBy = StpUtil.getLoginIdAsLong();
        
        // 检查课程权限
        if (!courseManagementService.hasPermission(createdBy, createDTO.getCourseId(), "write")) {
            throw new RuntimeException("无权限在该课程中创建考试");
        }

        Exam exam = new Exam();
        exam.setTitle(createDTO.getTitle());
        exam.setDescription(createDTO.getDescription());
        exam.setStartTime(createDTO.getStartTime());
        exam.setEndTime(createDTO.getEndTime());
        exam.setDurationMinutes(createDTO.getDurationMinutes());
        exam.setCreatedBy(createdBy);
        exam.setCourseId(createDTO.getCourseId());

        examMapper.insertExam(exam);
        Long examId = exam.getExamId();

        for (ExamCreateDTO.ExamQuestionDTO questionDTO : createDTO.getQuestions()) {
            ExamQuestion examQuestion = new ExamQuestion();
            examQuestion.setExamId(examId);
            examQuestion.setQuestionId(questionDTO.getQuestionId());
            examQuestion.setQuestionOrder(questionDTO.getQuestionOrder());
            examQuestion.setScore(questionDTO.getScore());
            examQuestionsMapper.insertExamQuestion(examQuestion);
        }

        return examId;
    }

    @Override
    public ExamDTO getExam(Long examId) {
        Exam exam = examMapper.selectExamById(examId);
        if (exam == null) {
            throw new RuntimeException("试卷不存在");
        }

        ExamDTO dto = new ExamDTO();
        dto.setExamId(exam.getExamId());
        dto.setTitle(exam.getTitle());
        dto.setDescription(exam.getDescription());
        dto.setStartTime(exam.getStartTime());
        dto.setEndTime(exam.getEndTime());
        dto.setDurationMinutes(exam.getDurationMinutes());
        dto.setCreatedBy(exam.getCreatedBy());
        dto.setCourseId(exam.getCourseId());
        dto.setCreatedAt(exam.getCreatedAt());
        dto.setUpdatedAt(exam.getUpdatedAt());
        
        // 计算试卷总分
        BigDecimal totalScore = examQuestionsMapper.calculateTotalScoreForExam(examId);
        dto.setTotalScore(totalScore);

        List<ExamQuestion> examQuestions = examQuestionsMapper.selectExamQuestionsByExamId(examId);
        List<ExamDTO.ExamQuestionDTO> questionDTOs = examQuestions.stream().map(eq -> {
            ExamDTO.ExamQuestionDTO questionDTO = new ExamDTO.ExamQuestionDTO();
            questionDTO.setExamQuestionId(eq.getExamQuestionId());
            questionDTO.setQuestionId(eq.getQuestionId());
            questionDTO.setQuestionOrder(eq.getQuestionOrder());
            questionDTO.setScore(eq.getScore());
            questionDTO.setQuestion(questionService.getQuestion(eq.getQuestionId()));
            return questionDTO;
        }).collect(Collectors.toList());
        dto.setQuestions(questionDTOs);

        return dto;
    }

    @Override
    @Transactional
    public void updateExam(ExamUpdateDTO updateDTO) {
        Exam exam = examMapper.selectExamById(updateDTO.getExamId());
        if (exam == null) {
            throw new RuntimeException("试卷不存在");
        }

        exam.setTitle(updateDTO.getTitle());
        exam.setDescription(updateDTO.getDescription());
        exam.setStartTime(updateDTO.getStartTime());
        exam.setEndTime(updateDTO.getEndTime());
        exam.setDurationMinutes(updateDTO.getDurationMinutes());
        examMapper.updateExam(exam);

        examQuestionsMapper.deleteExamQuestionsByExamId(updateDTO.getExamId());
        if (updateDTO.getQuestions() != null && !updateDTO.getQuestions().isEmpty()) {
            for (ExamUpdateDTO.ExamQuestionDTO questionDTO : updateDTO.getQuestions()) {
                ExamQuestion examQuestion = new ExamQuestion();
                examQuestion.setExamId(updateDTO.getExamId());
                examQuestion.setQuestionId(questionDTO.getQuestionId());
                examQuestion.setQuestionOrder(questionDTO.getQuestionOrder());
                examQuestion.setScore(questionDTO.getScore());
                examQuestionsMapper.insertExamQuestion(examQuestion);
            }
        }
    }

    @Override
    @Transactional
    public void deleteExam(Long examId) {
        Exam exam = examMapper.selectExamById(examId);
        if (exam == null) {
            throw new RuntimeException("试卷不存在");
        }

        examQuestionsMapper.deleteExamQuestionsByExamId(examId);
        examMapper.deleteExam(examId);
    }

    @Override
    public List<ExamDTO> listExamsByCreator() {
        Long createdBy = StpUtil.getLoginIdAsLong();
        List<Exam> exams = examMapper.selectExamsByCreator(createdBy);
        return exams.stream().map(exam -> {
            ExamDTO dto = new ExamDTO();
            dto.setExamId(exam.getExamId());
            dto.setTitle(exam.getTitle());
            dto.setDescription(exam.getDescription());
            dto.setStartTime(exam.getStartTime());
            dto.setEndTime(exam.getEndTime());
            dto.setDurationMinutes(exam.getDurationMinutes());
            dto.setCreatedBy(exam.getCreatedBy());
            dto.setCourseId(exam.getCourseId());
            dto.setCreatedAt(exam.getCreatedAt());
            dto.setUpdatedAt(exam.getUpdatedAt());
            
            // 计算试卷总分
            BigDecimal totalScore = examQuestionsMapper.calculateTotalScoreForExam(exam.getExamId());
            dto.setTotalScore(totalScore);

            List<ExamQuestion> examQuestions = examQuestionsMapper.selectExamQuestionsByExamId(exam.getExamId());
            List<ExamDTO.ExamQuestionDTO> questionDTOs = examQuestions.stream().map(eq -> {
                ExamDTO.ExamQuestionDTO questionDTO = new ExamDTO.ExamQuestionDTO();
                questionDTO.setExamQuestionId(eq.getExamQuestionId());
                questionDTO.setQuestionId(eq.getQuestionId());
                questionDTO.setQuestionOrder(eq.getQuestionOrder());
                questionDTO.setScore(eq.getScore());
                questionDTO.setQuestion(questionService.getQuestion(eq.getQuestionId()));
                return questionDTO;
            }).collect(Collectors.toList());
            dto.setQuestions(questionDTOs);

            return dto;
        }).collect(Collectors.toList());
    }
    
    @Override
    public StudentExamDTO getStudentExam(Long examId) {
        Exam exam = examMapper.selectExamById(examId);
        if (exam == null) {
            throw new RuntimeException("试卷不存在");
        }

        StudentExamDTO dto = new StudentExamDTO();
        dto.setExamId(exam.getExamId());
        dto.setTitle(exam.getTitle());
        dto.setDescription(exam.getDescription());
        dto.setStartTime(exam.getStartTime());
        dto.setEndTime(exam.getEndTime());
        dto.setDurationMinutes(exam.getDurationMinutes());
        dto.setCreatedBy(exam.getCreatedBy());
        dto.setCourseId(exam.getCourseId());
        dto.setCreatedAt(exam.getCreatedAt());
        dto.setUpdatedAt(exam.getUpdatedAt());
        
        // 计算试卷总分
        BigDecimal totalScore = examQuestionsMapper.calculateTotalScoreForExam(examId);
        dto.setTotalScore(totalScore);

        List<ExamQuestion> examQuestions = examQuestionsMapper.selectExamQuestionsByExamId(examId);
        List<StudentExamDTO.StudentExamQuestionDTO> questionDTOs = examQuestions.stream().map(eq -> {
            StudentExamDTO.StudentExamQuestionDTO questionDTO = new StudentExamDTO.StudentExamQuestionDTO();
            questionDTO.setExamQuestionId(eq.getExamQuestionId());
            questionDTO.setQuestionId(eq.getQuestionId());
            questionDTO.setQuestionOrder(eq.getQuestionOrder());
            questionDTO.setScore(eq.getScore());
            
            // 获取题目信息但不包含答案
            QuestionDTO fullQuestion = questionService.getQuestion(eq.getQuestionId());
            StudentExamDTO.StudentQuestionDTO studentQuestion = new StudentExamDTO.StudentQuestionDTO();
            studentQuestion.setQuestionId(fullQuestion.getQuestionId());
            studentQuestion.setContent(fullQuestion.getContent());
            studentQuestion.setQuestionType(fullQuestion.getQuestionType());
            studentQuestion.setSubject(fullQuestion.getSubject());
            studentQuestion.setDifficulty(fullQuestion.getDifficulty());
            studentQuestion.setCreatedBy(fullQuestion.getCreatedBy());
            studentQuestion.setCourseId(fullQuestion.getCourseId());
            studentQuestion.setCreatedAt(fullQuestion.getCreatedAt());
            studentQuestion.setUpdatedAt(fullQuestion.getUpdatedAt());
            
            // 转换选项但不包含正确答案标识
            if (fullQuestion.getOptions() != null) {
                List<StudentExamDTO.StudentQuestionOptionDTO> studentOptions = fullQuestion.getOptions().stream().map(option -> {
                    StudentExamDTO.StudentQuestionOptionDTO studentOption = new StudentExamDTO.StudentQuestionOptionDTO();
                    studentOption.setOptionId(option.getOptionId());
                    studentOption.setQuestionId(option.getQuestionId());
                    studentOption.setContent(option.getContent());
                    studentOption.setOptionOrder(option.getOptionOrder());
                    // 不设置isCorrect字段
                    return studentOption;
                }).collect(Collectors.toList());
                studentQuestion.setOptions(studentOptions);
            }
            
            questionDTO.setQuestion(studentQuestion);
            return questionDTO;
        }).collect(Collectors.toList());
        dto.setQuestions(questionDTOs);

        return dto;
    }
    
    @Override
    public BigDecimal calculateTotalScore(Long examId) {
        return examQuestionsMapper.calculateTotalScoreForExam(examId);
    }
}
